﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Ro.AssistFunction.GUI;
using Ro.AssistFunction.OutputManage;
using Ro.AssistFunction.SerializerChildNodes;
using Ro.Common.RoArgs;
using Ro.Common.RoInterface.UserType;
using Ro.Interpreter.GuiAssist;
using RoTestGUI.GuiAssist;

namespace RoTestGUI
{
    public partial class WinMain : Form
    {
        /// <summary>
        /// 主函数
        /// </summary>
        public WinMain()
        {
            InitializeComponent(); //初始化
            InitImagelist.InitImageListForTcsTree(TcsTree); //初始化图片资源


            RoPubArgments.ProTips = true; //给定Pro的版本标定符-true,说明是通过GUI程序启动的测试
            RoPubArgments.SystemProperties = new List<Property>(); //初始化全参数List
            RoPubArgments.GuiTestArgsInfo = new GuiTestArgsInfo(); //初始化参数


            ConfFileState.Checked = false; //初始默认配置文件验证checkobx未选择
            TciFileState.Checked = false; //初始默认tci文件验证checkobx未选择
            Stop.Enabled = false; //初始默认停止按键是不可用

            GuiOutEvent.ChangeResult += ItemsAction_Result; //绑定UI更改事件
            GuiOutEvent.ChangeDetail += ItemsAction_Detail; //绑定UI更改事件
        }


        /// <summary>
        /// 运行脚本线程
        /// </summary>
        private Thread _runThread;


        /// <summary>
        /// 代表事件，事件注册到MainWindow内
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void EventHandle(object sender, EventArgs e);


        /// <summary>
        /// 勾选Tcs文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SelectTcs_Click(object sender, EventArgs e)
        {
            TcsTree.LabelEdit = true; //可编辑状态
            TcsTree.Nodes.Clear(); //每次都清除全部

            //弹出文件夹选择框
            FolderBrowserDialog fbd = new FolderBrowserDialog
            {
                Description = @"选取Tcs文件夹",
                ShowNewFolderButton = false
            };
            if (fbd.ShowDialog() == DialogResult.OK || fbd.ShowDialog() == DialogResult.Yes)
            {
                //给定tcs文件夹路径
                RoPubArgments.GuiTestArgsInfo.TcsFolderPath = fbd.SelectedPath;
                //初始化
                GetAllTcsFile getAllTcsFile = new GetAllTcsFile(RoPubArgments.GuiTestArgsInfo.TcsFolderPath);
                TcsTree.Nodes.Add(getAllTcsFile.RootNode);
                TcsTree.ExpandAll(); //全展开
                CheckTreeView.CheckAllTreeNodes(getAllTcsFile.RootNode); //默认全部勾选
            }
            else
            {
                MessageBox.Show(@"没有选择测试脚本文件", @"警告");
            }
        }


        /// <summary>
        /// 勾选Tci文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SelectTci_Click(object sender, EventArgs e)
        {
            //弹出文件夹选择框
            FolderBrowserDialog fbd = new FolderBrowserDialog
            {
                Description = @"选取Tci文件夹",
                ShowNewFolderButton = false
            };
            if (fbd.ShowDialog() == DialogResult.OK || fbd.ShowDialog() == DialogResult.Yes)
            {
                //给定tcs文件夹路径
                RoPubArgments.GuiTestArgsInfo.TciFolderPath = fbd.SelectedPath;
                TciFileState.Checked = true;
                MessageBox.Show(@"Tci文件夹已成功载入", @"成功");
            }
            else
            {
                MessageBox.Show(@"没有选择Tci文件夹", @"警告");
            }
        }


        /// <summary>
        /// 载入配置Tcc文件，允许载入多份
        /// <para>原则上，tcc文件是全部载入</para>
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ConfigMenu_Click(object sender, EventArgs e)
        {
            //弹出文件夹选择框
            FolderBrowserDialog fbd = new FolderBrowserDialog
            {
                Description = @"选取Tcc配置文件夹",
                ShowNewFolderButton = false
            };
            if (fbd.ShowDialog() == DialogResult.OK || fbd.ShowDialog() == DialogResult.Yes)
            {
                //给定tcc文件夹路径
                RoPubArgments.GuiTestArgsInfo.TccFolderPath = fbd.SelectedPath;
                ConfFileState.Checked = true;
                //启动tcc协助方法，返回固定的GuiArgs中的对应值,供其他方法使用
                NewSerChildNode newSerChildNode = new NewSerChildNode();
                RoPubArgments.GuiTccInfo = newSerChildNode.SerGuiTccInfo(RoPubArgments.GuiTestArgsInfo.TccFolderPath);

                MessageBox.Show(@"配置文件夹已成功载入", @"成功");
            }
            else
            {
                MessageBox.Show(@"没有选择配置文件夹", @"警告");
            }
        }


        /// <summary>
        /// 刷新按钮，刷新Tcs文件夹
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RefreshBtn_Click(object sender, EventArgs e)
        {
            if (TcsTree.Nodes.Count > 0)
            {
                TcsTree.LabelEdit = true; //可编辑状态
                TcsTree.Nodes.Clear(); //每次都清除全部

                //初始化
                GetAllTcsFile getAllTcsFile = new GetAllTcsFile(RoPubArgments.GuiTestArgsInfo.TcsFolderPath);
                TcsTree.Nodes.Add(getAllTcsFile.RootNode);
                TcsTree.ExpandAll(); //全展开
                CheckTreeView.CheckAllTreeNodes(getAllTcsFile.RootNode); //默认全部勾选
            }
            else
            {
                MessageBox.Show(@"未选择Tcs文件夹", @"警告");
            }
        }


        /// <summary>
        /// 清除显示的log
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Clear_Click(object sender, EventArgs e)
        {
            LogDetails.Items.Clear();
            ResultDetails.Items.Clear();
        }


        /// <summary>
        /// 运行按钮
        /// 点击运行后，自动运行选定的脚本
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Run_Click(object sender, EventArgs e)
        {
            LogDetails.Items.Clear(); //清除整个log lsit
            ResultDetails.Items.Clear(); //清除整个result lsit

            //判断Tcs的Tree的勾选情况，只有勾选的tcs文件才会运行
            //todo 执行脚本(需要写在解释器Core中) 带入TcsTree

            if (ConfFileState.Checked && TciFileState.Checked)
            {
                TreeNode root = TcsTree.Nodes[0];
                _runThread = new Thread(RunT) {IsBackground = true};
                _runThread.Start(root);
            }
            else
            {
                MessageBox.Show(@"没有选择Tcc文件夹或Tci文件夹", @"警告");
            }
        }


        /// <summary>
        /// 停止进程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Stop_Click(object sender, EventArgs e)
        {
            _runThread.Abort();
            ChangeBtnEnable(true, false);
        }


        /// <summary>
        /// 双击差看详情
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ResultDetails_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ListViewHitTestInfo info = ResultDetails.HitTest(e.X, e.Y);
            if (info.Item != null)
            {
                ProOutToGui proOutToGui = new ProOutToGui
                {
                    Name = info.Item.SubItems[1].Text,
                    StepsName = info.Item.SubItems[2].Text,
                    ControlId = info.Item.SubItems[3].Text,
                    Result = info.Item.SubItems[4].Text,
                    ExtraInfo = info.Item.SubItems[5].Text
                };

                ViewDetails viewDetails = new ViewDetails();
                viewDetails.SetResultValue(proOutToGui);
                viewDetails.ShowDialog();
            }
        }


        /// <summary>
        /// 双击查看Log详情
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LogDetails_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ListViewHitTestInfo info = LogDetails.HitTest(e.X, e.Y);
            if (info.Item != null)
            {
                ProOutToGui proOutToGui = new ProOutToGui
                {
                    TimeFlag = info.Item.SubItems[1].Text,
                    Details = info.Item.SubItems[2].Text
                };

                ViewDetails viewDetails = new ViewDetails();
                viewDetails.SetLogValue(proOutToGui);
                viewDetails.ShowDialog();
            }
        }

        /// <summary>
        /// 勾选后的事件处理
        /// <para>勾选父节点，子节点全部勾选</para>
        /// <para>取消时，勾选子节点，父节点取消</para>
        /// <para>取消时，勾选父节点，子节点全部取消</para>
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TcsTree_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action == TreeViewAction.ByMouse)
            {
                if (e.Node.Checked)
                {
                    //选中节点，选中其子节点
                    CheckTreeView.SetChildNodeCheckedState(e.Node, true);
                }
                else
                {
                    //取消选中，取消其子节点
                    CheckTreeView.SetChildNodeCheckedState(e.Node, false);
                    if (e.Node.Parent != null)
                    {
                        //如果存在父节点，则取消对应的父节点
                        CheckTreeView.SetParentNodeCheckedState(e.Node, false);
                    }
                }
            }
        }


        /// <summary>
        /// 退出程序
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ExitMenu_Click(object sender, EventArgs e)
        {
            Process[] process = Process.GetProcesses();
            Process sig = (from sigpro in process where sigpro.ProcessName.Contains("chromedriver") select sigpro).FirstOrDefault();
            if (sig != null)
            {
                sig.Kill();
                sig.Dispose();
            }
            Environment.Exit(0);
        }

        /*###################################################################################################
                 * 私有方法
                 ###################################################################################################*/

        /// <summary>
        /// 运行执行
        /// </summary>
        /// <param name="rootNode"></param>
        private void RunT(object rootNode)
        {
            ChangeBtnEnable(false, true);
            GuiAction guiAction = new GuiAction(rootNode as TreeNode);
            MessageBox.Show(@"运行完成！", @"通知");
            ChangeBtnEnable(true, false);
        }


        /*###################################################################################################
                 * 更新UI线程方法
                 ###################################################################################################*/

        /// <summary>
        /// 更改运行和停止的按钮状态
        /// </summary>
        /// <param name="run"></param>
        /// <param name="stop"></param>
        private void ChangeBtnEnable(bool run, bool stop)
        {
            if (Run.InvokeRequired && Stop.InvokeRequired)
            {
                Invoke(new Action(() =>
                {
                    Run.Enabled = run;
                    Stop.Enabled = stop;
                }));
            }
            else
            {
                Run.Enabled = run;
                Stop.Enabled = stop;
            }
        }

        /// <summary>
        /// 更改UI界面
        /// 具体执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ItemsAction_Result(object sender, ProOutToGui e)
        {
            if (LogDetails.InvokeRequired)
            {
                GuiOutEvent.InvokeReuslt invokeReuslt = ItemsAction_Result;
                Invoke(invokeReuslt, sender, e);
            }
            else
            {
                ListViewItem item = ResultDetails.Items.Add((ResultDetails.Items.Count + 1) + "");
                item.SubItems.Add(e.Name);
                item.SubItems.Add(e.StepsName);
                item.SubItems.Add(e.ControlId);
                item.SubItems.Add(e.Result);
                item.SubItems.Add(e.ExtraInfo);
                item.EnsureVisible();
            }
        }

        /// <summary>
        /// 更改UI界面
        /// 具体执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ItemsAction_Detail(object sender, ProOutToGui e)
        {
            if (LogDetails.InvokeRequired)
            {
                GuiOutEvent.InvokeDetails invokeDetails = ItemsAction_Detail;
                Invoke(invokeDetails, sender, e);
            }
            else
            {
                ListViewItem item = LogDetails.Items.Add((LogDetails.Items.Count + 1) + "");
                item.SubItems.Add(e.TimeFlag);
                item.SubItems.Add(e.Details);
                item.EnsureVisible();
            }
        }
    }
}
